﻿#pragma execution_character_set("utf-8")
#include <QUdpSocket>
#include <QtNetwork/QNetworkInterface>
#include <QDebug>
#include <QTimer>
#include "systimer.h"
#include "udpsys.h"
#include "reporter.h"

void Systimer::timerEvent(QTimerEvent *)
{
    static long time_count = 0;
    QString testCMD;
    time_count++;

    refreshDevStatus();     /* 每1S刷新一次下位机节点状态 */

    if(!isStartTestCase){
        return;
    }

    if(time_count%3 != 0)
        return;

    /* 每3S 检测一次命令执行状态 */
    bool isAllEnded = true;
    for(int i=0; i<udpDeviceList.length(); i++){

        if(udpDeviceList.at(i).status >  STAT_NORMAL){
            /* 设备状态被手动更改 */
            switch(udpDeviceList.at(i).status){
            case STAT_DISABLE:
                emit testDevStatTrigger(i, LOG_WARN, "设备节点删除");
                udpDeviceList[i].status = STAT_DISABLED;
                emit testDevTrigger(i, false, 0, 0, STAT_DISABLED);
                break;
            case STAT_STOP:
                emit testDevStatTrigger(i, LOG_WARN, "已停止测试[手动]");
                udpDeviceList[i].status = STAT_STOPED;
                emit testDevTrigger(i, true, 0, 0, STAT_STOPED);
                break;
            case STAT_RESTART:
                isAllEnded = false;
                emit testDevStatTrigger(i, LOG_WARN, "重新启动测试中...");
                udpDeviceList[i].isRuning = false;
                udpDeviceList[i].cmdIndex = 0;
                udpDeviceList[i].testCounts  = 1;
                udpDeviceList[i].isTestEnded = false;
                udpDeviceList[i].testTotalUseTimes = 0;
                udpDeviceList[i].status   = STAT_RESTARTED;
                emit testDevTrigger(i, true, 0, 0, STAT_NORMAL);
                starteOneOrder(i, "reboot", 50);
                starteOneOrderLater(i, "reboot", 50, 3);
                break;
            case STAT_RESTARTED:
                isAllEnded = false;
                break;
            }
        }else{
            if(udpDeviceList.at(i).isRuning == false){              // 设备当前处于未执行命令状态，开始执行下一个命令
                int cmdIndex = udpDeviceList.at(i).cmdIndex;
                if(cmdIndex < testCaseList.length()){               // 测试项开始
                    isAllEnded = false;
                    testCMD = testCaseList.at(cmdIndex).cmd;
                    if(testCMD.contains("reboot")){
                        udpDeviceList[i].isReboot = true;
                    }else
                        udpDeviceList[i].isReboot = false;
                    udpDeviceList[i].isRuning = true;
                    udpDeviceList[i].isRebooted = false;
                    udpDeviceList[i].startCmdTime = QDateTime::currentDateTime().toTime_t();
                    if(udpDeviceList.at(i).testCounts == 1){		// 单项命令，多次测试的第一项，记录开始时间
                        udpDeviceList[i].startTestTime = udpDeviceList[i].startCmdTime;
                    }
                    udpDeviceList[i].cmdOutStr = "";

                    emit testDevTrigger(i, true, cmdIndex, udpDeviceList.at(i).testCounts, STAT_NORMAL);
                    if(udpDeviceList.at(i).isReboot){
                        emit testDevStatTrigger(i, LOG_WARN, "重启中...");
                    }else{
                        emit testDevStatTrigger(i, LOG_INFO, "正常测试中...");
                    }
                    starteOneOrder(i, testCMD, testCaseList.at(cmdIndex).timeMax);
                    starteOneOrderLater(i, testCMD, testCaseList.at(cmdIndex).timeMax, 3);              // 重复发送两次
                }else{                                              // 测试实例已经执行完毕
                    if(!udpDeviceList.at(i).isTestEnded){
                        udpDeviceList[i].isTestEnded = true;
                        emit testDevTrigger(i, true, cmdIndex, udpDeviceList.at(i).testCounts, STAT_NORMAL);

                        if(isTestendPoweroff){
                            emit testDevStatTrigger(i, LOG_WARN, "测试完成，设备关机");
                            starteOneOrder(i,       "poweroff", 60);
                            starteOneOrderLater(i,  "poweroff", 60, 6);              // 重复发送两次
                        }else {
                            emit testDevStatTrigger(i, LOG_INFO, "测试完成");
                        }
                    }
                }
            }else{                                                  // 设备当前正在执行命令
                if(udpDeviceList.at(i).status == STAT_NORMAL){
                    isAllEnded = false;
                }

                /* 检查设备是否正在重启，刷新在时间 */
                if(udpDeviceList.at(i).isReboot){

                    if(udpDeviceList[i].isRebooted){
                        if(QDateTime::currentDateTime().toTime_t() - udpDeviceList.at(i).lastOnlineTime < 15){
                            // 系统已经正常重启过了，现在认定为命令执行结束
                            udpDeviceList[i].isRuning = false;
                            int cmdIndex = udpDeviceList[i].cmdIndex;
                            if(udpDeviceList[i].cmdResult.size() <= cmdIndex){          // 该条测试命令结果不存在
                                udpDeviceList[i].cmdResult.append("");                  // 创建个空的结果
                            }else{
                                udpDeviceList[i].cmdResult[cmdIndex].append("\n");
                            }
                            udpDeviceList[i].cmdResult[cmdIndex].append("ok");
                            udpDeviceList[i].cmdOutStr.clear();
                            int testCounts = udpDeviceList[i].testCounts;
                            udpDeviceList[i].testCounts         += 1;
                            udpDeviceList[i].testTotalCounts    += 1;
                            if(udpDeviceList[i].testCounts > testCaseList.at(cmdIndex).counts){      //当前测试次数达到要求
                                udpDeviceList[i].cmdIndex = udpDeviceList[i].cmdIndex+1;
                                udpDeviceList[i].testCounts = 1;
                                udpDeviceList[i].cmdResult[cmdIndex] = resultHandle(udpDeviceList[i].cmdResult[cmdIndex], cmdIndex);
                                udpDeviceList[i].testTimes.append(static_cast<int>(QDateTime::currentDateTime().toTime_t() - udpDeviceList.at(i).startTestTime));
                            }
                            appendLog(QString("cmd(%1) from box_%2, ip:%3-命令执行结束-'%4S'，第%5次测试结果：%6")
                                      .arg(testCaseList.at(cmdIndex).cmd).arg(i).arg(udpDeviceList.at(i).ipAddress)
                                      .arg(QDateTime::currentDateTime().toTime_t() - udpDeviceList.at(i).startTestTime).arg(testCounts).arg("ok"), LOG_INFO);
                        }
                    }else{
                        if(QDateTime::currentDateTime().toTime_t() - udpDeviceList.at(i).lastOnlineTime > 25){      // 下位机节点超过25S没有响应，已执行过重启
                            udpDeviceList[i].isRebooted = true;
                            appendLog(QString("offline: may %1 is rebooted.").arg(udpDeviceList.at(i).ipAddress), LOG_DEBUG);
                        }else {
                            starteOneOrder(i, "reboot", 60);              // 发现仍然没关机，多发送几次重启命令
                        }
                    }
                }else{
                    /* 设备正在执行命令，刷新执行时间 */
                    int cmdIndex = udpDeviceList.at(i).cmdIndex;
                    unsigned long curTime = QDateTime::currentDateTime().toTime_t();
                    int runTimes = static_cast<int>(curTime - udpDeviceList.at(i).startCmdTime);
                    int timeMaxs = testCaseList.at(cmdIndex).timeMax;

                    if(runTimes > 2*timeMaxs){
                        // 运行时间超出2倍的预期超时时间
                        if(udpDeviceList.at(i).status == STAT_NORMAL){
                            udpDeviceList[i].status = STAT_ERR_TIMEOUT;
                        }
                    }
                }
            }
        }
    }

    if(isAllEnded && isStartTestCase){
        autoTestSwitch(false, false);
        emit testAllEned();
    }
}
